import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path

# 设置中文字体（避免乱码）
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题


def plot_acc_comparison(csv_path: str = "../experiment_metrics.csv"):
    """绘制模型准确率对比柱状图（带误差线）"""
    df = pd.read_csv(csv_path)
    plt.figure(figsize=(10, 6))

    # 柱状图+误差线（均值±标准差）
    sns.barplot(
        x="模型名称",
        y="均值准确率",
        data=df,
        yerr=df["标准差"],
        capsize=0.1,
        palette="Set2"
    )

    plt.title("不同模型在MNIST上的准确率对比（3次重复实验）", fontsize=14)
    plt.xlabel("模型", fontsize=12)
    plt.ylabel("验证准确率（均值±标准差）", fontsize=12)
    plt.ylim(0.97, 1.0)  # 根据实际数据调整范围
    plt.grid(axis="y", linestyle="--", alpha=0.7)
    plt.tight_layout()
    plt.savefig("../acc_comparison.png", dpi=300)
    print("准确率对比图保存至 acc_comparison.png")


def plot_acc_boxplot(models: list = None):
    """绘制准确率箱线图（展示各轮次分布）"""
    if models is None:
        models = ["simple_cnn", "lenet5", "multi_scale_cnn"]

    # 构建长表格数据
    plot_data = []
    for model in models:
        model_name = model.replace("_", " ")
        # 从提取的CSV中读取数据，或直接调用extract_single_model_metrics
        metrics = extract_single_model_metrics(model)  # 需要导入extract_single_model_metrics
        for acc in metrics["轮次准确率"]:
            plot_data.append({"模型": model_name, "准确率": acc})

    plot_df = pd.DataFrame(plot_data)
    plt.figure(figsize=(10, 6))
    sns.boxplot(x="模型", y="准确率", data=plot_df, palette="Set3")
    plt.title("不同模型准确率分布（3次重复实验）", fontsize=14)
    plt.ylim(0.97, 1.0)
    plt.grid(axis="y", linestyle="--", alpha=0.7)
    plt.tight_layout()
    plt.savefig("../acc_boxplot.png", dpi=300)
    print("准确率箱线图保存至 acc_boxplot.png")


if __name__ == "__main__":
    # 先运行提取脚本生成CSV，再可视化
    if not Path("../experiment_metrics.csv").exists():
        from extract_results import extract_all_models

        extract_all_models(runs=3)

    plot_acc_comparison()
    plot_acc_boxplot()